package com.smart.community.region.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;

import com.smart.community.region.vo.PageResult;
import com.smart.community.region.vo.ResidentHouseholdVO;

import lombok.extern.slf4j.Slf4j;

/**
 * 住户管理缓存服务
 * 
 * @author Wu.Liang
 * @since 2025-07-28
 */
@Service
@Slf4j
public class ResidentCacheService {

    @Autowired
    private CacheManager cacheManager;

    // 缓存区域名称
    private static final String CACHE_RESIDENT = "resident";
    private static final String CACHE_RESIDENT_HOUSEHOLD = "residentHousehold";
    private static final String CACHE_HOUSEHOLD = "household";
    private static final String CACHE_RESIDENT_OPTIONS = "residentOptions";
    private static final String CACHE_RESIDENT_STATISTICS = "residentStatistics";
    private static final String CACHE_RESIDENT_SEARCH = "residentSearch";

    /**
     * 缓存住户基本信息
     * 
     * @param residentId 住户ID
     * @param resident 住户信息
     */
    public void cacheResident(Long residentId, Object resident) {
        try {
            Cache cache = cacheManager.getCache(CACHE_RESIDENT);
            if (cache != null) {
                cache.put("resident:" + residentId, resident);
                log.debug("缓存住户信息成功，住户ID: {}", residentId);
            }
        } catch (Exception e) {
            log.error("缓存住户信息失败，住户ID: {}", residentId, e);
        }
    }

    /**
     * 获取缓存的住户信息
     * 
     * @param residentId 住户ID
     * @return 住户信息
     */
    public Object getCachedResident(Long residentId) {
        try {
            Cache cache = cacheManager.getCache(CACHE_RESIDENT);
            if (cache != null) {
                Cache.ValueWrapper wrapper = cache.get("resident:" + residentId);
                if (wrapper != null) {
                    log.debug("从缓存获取住户信息成功，住户ID: {}", residentId);
                    return wrapper.get();
                }
            }
        } catch (Exception e) {
            log.error("从缓存获取住户信息失败，住户ID: {}", residentId, e);
        }
        return null;
    }

    /**
     * 缓存房户住户列表
     * 
     * @param householdId 房户ID
     * @param current 当前页
     * @param size 每页大小
     * @param result 查询结果
     */
    public void cacheResidentList(Long householdId, Integer current, Integer size, PageResult<ResidentHouseholdVO> result) {
        try {
            Cache cache = cacheManager.getCache(CACHE_RESIDENT_HOUSEHOLD);
            if (cache != null) {
                String key = String.format("household:%d:residents:page:%d:size:%d", householdId, current, size);
                cache.put(key, result);
                log.debug("缓存房户住户列表成功，房户ID: {}, 页码: {}, 大小: {}", householdId, current, size);
            }
        } catch (Exception e) {
            log.error("缓存房户住户列表失败，房户ID: {}, 页码: {}, 大小: {}", householdId, current, size, e);
        }
    }

    /**
     * 获取缓存的房户住户列表
     * 
     * @param householdId 房户ID
     * @param current 当前页
     * @param size 每页大小
     * @return 查询结果
     */
    @SuppressWarnings("unchecked")
    public PageResult<ResidentHouseholdVO> getCachedResidentList(Long householdId, Integer current, Integer size) {
        try {
            Cache cache = cacheManager.getCache(CACHE_RESIDENT_HOUSEHOLD);
            if (cache != null) {
                String key = String.format("household:%d:residents:page:%d:size:%d", householdId, current, size);
                Cache.ValueWrapper wrapper = cache.get(key);
                if (wrapper != null) {
                    log.debug("从缓存获取房户住户列表成功，房户ID: {}, 页码: {}, 大小: {}", householdId, current, size);
                    return (PageResult<ResidentHouseholdVO>) wrapper.get();
                }
            }
        } catch (Exception e) {
            log.error("从缓存获取房户住户列表失败，房户ID: {}, 页码: {}, 大小: {}", householdId, current, size, e);
        }
        return null;
    }

    /**
     * 缓存住户选项列表
     * 
     * @param options 住户选项列表
     */
    public void cacheResidentOptions(List<?> options) {
        try {
            Cache cache = cacheManager.getCache(CACHE_RESIDENT_OPTIONS);
            if (cache != null) {
                cache.put("resident:options", options);
                log.debug("缓存住户选项列表成功，数量: {}", options.size());
            }
        } catch (Exception e) {
            log.error("缓存住户选项列表失败", e);
        }
    }

    /**
     * 获取缓存的住户选项列表
     * 
     * @return 住户选项列表
     */
    @SuppressWarnings("unchecked")
    public List<?> getCachedResidentOptions() {
        try {
            Cache cache = cacheManager.getCache(CACHE_RESIDENT_OPTIONS);
            if (cache != null) {
                Cache.ValueWrapper wrapper = cache.get("resident:options");
                if (wrapper != null) {
                    log.debug("从缓存获取住户选项列表成功");
                    return (List<?>) wrapper.get();
                }
            }
        } catch (Exception e) {
            log.error("从缓存获取住户选项列表失败", e);
        }
        return null;
    }

    /**
     * 缓存住户统计信息
     * 
     * @param statistics 统计信息
     */
    public void cacheResidentStatistics(Object statistics) {
        try {
            Cache cache = cacheManager.getCache(CACHE_RESIDENT_STATISTICS);
            if (cache != null) {
                cache.put("resident:statistics", statistics);
                log.debug("缓存住户统计信息成功");
            }
        } catch (Exception e) {
            log.error("缓存住户统计信息失败", e);
        }
    }

    /**
     * 获取缓存的住户统计信息
     * 
     * @return 统计信息
     */
    public Object getCachedResidentStatistics() {
        try {
            Cache cache = cacheManager.getCache(CACHE_RESIDENT_STATISTICS);
            if (cache != null) {
                Cache.ValueWrapper wrapper = cache.get("resident:statistics");
                if (wrapper != null) {
                    log.debug("从缓存获取住户统计信息成功");
                    return wrapper.get();
                }
            }
        } catch (Exception e) {
            log.error("从缓存获取住户统计信息失败", e);
        }
        return null;
    }

    /**
     * 缓存住户搜索结果
     * 
     * @param searchKey 搜索关键词
     * @param result 搜索结果
     */
    public void cacheResidentSearch(String searchKey, Object result) {
        try {
            Cache cache = cacheManager.getCache(CACHE_RESIDENT_SEARCH);
            if (cache != null) {
                cache.put("resident:search:" + searchKey, result);
                log.debug("缓存住户搜索结果成功，搜索关键词: {}", searchKey);
            }
        } catch (Exception e) {
            log.error("缓存住户搜索结果失败，搜索关键词: {}", searchKey, e);
        }
    }

    /**
     * 获取缓存的住户搜索结果
     * 
     * @param searchKey 搜索关键词
     * @return 搜索结果
     */
    public Object getCachedResidentSearch(String searchKey) {
        try {
            Cache cache = cacheManager.getCache(CACHE_RESIDENT_SEARCH);
            if (cache != null) {
                Cache.ValueWrapper wrapper = cache.get("resident:search:" + searchKey);
                if (wrapper != null) {
                    log.debug("从缓存获取住户搜索结果成功，搜索关键词: {}", searchKey);
                    return wrapper.get();
                }
            }
        } catch (Exception e) {
            log.error("从缓存获取住户搜索结果失败，搜索关键词: {}", searchKey, e);
        }
        return null;
    }

    /**
     * 清除住户相关缓存
     * 
     * @param residentId 住户ID
     */
    public void evictResidentCache(Long residentId) {
        try {
            // 清除住户基本信息缓存
            Cache residentCache = cacheManager.getCache(CACHE_RESIDENT);
            if (residentCache != null) {
                residentCache.evict("resident:" + residentId);
            }

            // 清除住户选项缓存（因为可能包含该住户）
            Cache optionsCache = cacheManager.getCache(CACHE_RESIDENT_OPTIONS);
            if (optionsCache != null) {
                optionsCache.clear();
            }

            // 清除住户统计信息缓存
            Cache statisticsCache = cacheManager.getCache(CACHE_RESIDENT_STATISTICS);
            if (statisticsCache != null) {
                statisticsCache.clear();
            }

            // 清除住户搜索缓存
            Cache searchCache = cacheManager.getCache(CACHE_RESIDENT_SEARCH);
            if (searchCache != null) {
                searchCache.clear();
            }

            log.info("清除住户相关缓存成功，住户ID: {}", residentId);
        } catch (Exception e) {
            log.error("清除住户相关缓存失败，住户ID: {}", residentId, e);
        }
    }

    /**
     * 清除房户住户列表缓存
     * 
     * @param householdId 房户ID
     */
    public void evictResidentListCache(Long householdId) {
        try {
            Cache cache = cacheManager.getCache(CACHE_RESIDENT_HOUSEHOLD);
            if (cache != null) {
                // 清除该房户的所有分页缓存
                cache.evictIfPresent("household:" + householdId + ":residents:*");
                log.info("清除房户住户列表缓存成功，房户ID: {}", householdId);
            }
        } catch (Exception e) {
            log.error("清除房户住户列表缓存失败，房户ID: {}", householdId, e);
        }
    }

    /**
     * 清除所有住户相关缓存
     */
    public void evictAllResidentCache() {
        try {
            // 清除所有住户相关缓存区域
            String[] cacheNames = {
                    CACHE_RESIDENT,
                    CACHE_RESIDENT_HOUSEHOLD,
                    CACHE_RESIDENT_OPTIONS,
                    CACHE_RESIDENT_STATISTICS,
                    CACHE_RESIDENT_SEARCH
            };

            for (String cacheName : cacheNames) {
                Cache cache = cacheManager.getCache(cacheName);
                if (cache != null) {
                    cache.clear();
                }
            }

            log.info("清除所有住户相关缓存成功");
        } catch (Exception e) {
            log.error("清除所有住户相关缓存失败", e);
        }
    }

    /**
     * 获取缓存统计信息
     * 
     * @return 缓存统计信息
     */
    public String getCacheStatistics() {
        StringBuilder stats = new StringBuilder();
        stats.append("住户管理缓存统计信息:\n");
        
        String[] cacheNames = {
                CACHE_RESIDENT,
                CACHE_RESIDENT_HOUSEHOLD,
                CACHE_RESIDENT_OPTIONS,
                CACHE_RESIDENT_STATISTICS,
                CACHE_RESIDENT_SEARCH
        };

        for (String cacheName : cacheNames) {
            Cache cache = cacheManager.getCache(cacheName);
            if (cache != null) {
                stats.append(String.format("- %s: 可用\n", cacheName));
            } else {
                stats.append(String.format("- %s: 不可用\n", cacheName));
            }
        }

        return stats.toString();
    }
} 